Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

http2: refactor read mechanism #18030

Closed
wants to merge 2 commits into from

Conversation

addaleax
Copy link
Member

@addaleax addaleax commented Jan 8, 2018

The first commit is from #18020 to avoid merge conflicts.

  • src: introduce internal buffer slice constructor

    Add a C++ variant of Buffer.from(arrayBuffer, offset, length).

  • http2: refactor read mechanism

    Refactor the read mechanism to completely avoid copying.

    Instead of copying individual DATA frame contents into buffers,
    create ArrayBuffer instances for all socket reads and emit
    slices of those ArrayBuffers to JS.

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included (note that the added test passes independently of this change)
  • commit message follows commit guidelines
Affected core subsystem(s)

/cc @nodejs/http2

@addaleax addaleax added blocked PRs that are blocked by other issues or PRs. http2 Issues or PRs related to the http2 subsystem. labels Jan 8, 2018
@nodejs-github-bot nodejs-github-bot added the lib / src Issues and PRs related to general changes in the lib or src directory. label Jan 8, 2018
@@ -357,6 +357,19 @@ v8::MaybeLocal<v8::Object> New(Environment* env,
// Mixing operator new and free() is undefined behavior so don't do that.
v8::MaybeLocal<v8::Object> New(Environment* env, char* data, size_t length);

inline
v8::MaybeLocal<v8::Uint8Array> New(Environment* env,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to explicitly note that a HandleScope must have been opened before calling this function?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TimothyGu I think that’s kind of explicit in the fact that this returns a MaybeLocal; that’s never valid without a HandleScope, right?

(Or, the other way around: The same is true of the other buffer constructors, but we don’t mention it there.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's certainly true. But the other Buffer constructors open a HandleScope themselves so I was wondering.

Copy link
Member Author

@addaleax addaleax Jan 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TimothyGu I removed it in this case because, as far as I can tell, all the temporary handles created here refer to objects that are kept alive be the returned Buffer instance anyway.

If my understanding is correct, I think they could be removed in the other cases as well, but I am not 100 % sure and since some of them are public API I left them the way they were.

exports.mustCallAsync = function(fn, exact) {
return exports.mustCall((...args) => {
fn(...args).then(exports.mustCall());
}, exact);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the returned function return a promise as well, so that one could chain the functions returned by mustCallAsync?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TimothyGu yup, done!

@@ -467,6 +469,10 @@ function doNotify() {
// Set up the callback used to receive PerformanceObserver notifications
function observersCallback(entry) {
const type = mapTypes(entry.entryType);

if (type === NODE_PERFORMANCE_ENTRY_TYPE_HTTP2)
collectStats(entry);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer we didn't define these here, but rather in the HTTP2 part. I think these are also defined for every single instance, which will increase overhead.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mcollina Can you comment that on @jasnell’s #18020? :)

Copy link
Member

@jasnell jasnell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. Did you benchmark this at all? It should yield a nice modest boost.

@addaleax
Copy link
Member Author

addaleax commented Jan 8, 2018

@jasnell I got about + 3 % in the simple benchmark but I’ll kick off a benchmark CI after #18020 has been merged :)

Add a C++ variant of `Buffer.from(arrayBuffer, offset, length)`.
Refactor the read mechanism to completely avoid copying.

Instead of copying individual `DATA` frame contents into buffers,
create `ArrayBuffer` instances for all socket reads and emit
slices of those `ArrayBuffer`s to JS.
@addaleax addaleax removed the blocked PRs that are blocked by other issues or PRs. label Jan 13, 2018
@addaleax
Copy link
Member Author

@addaleax
Copy link
Member Author

@nodejs/benchmarking https://ci.nodejs.org/view/Node.js%20benchmark/job/benchmark-node-micro-benchmarks/93/console says

Error: Requested benchmarker 'h2load' is not installed

Is there anything we can do about that?

@jasnell
Copy link
Member

jasnell commented Jan 13, 2018

Ping @nodejs/build

@addaleax addaleax added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Jan 18, 2018
@addaleax
Copy link
Member Author

Landed in da30788, 0625627

@addaleax addaleax closed this Jan 18, 2018
@addaleax addaleax deleted the http2-inbound-nocopy branch January 18, 2018 21:50
addaleax added a commit that referenced this pull request Jan 18, 2018
Add a C++ variant of `Buffer.from(arrayBuffer, offset, length)`.

PR-URL: #18030
Reviewed-By: James M Snell <jasnell@gmail.com>
addaleax added a commit that referenced this pull request Jan 18, 2018
Refactor the read mechanism to completely avoid copying.

Instead of copying individual `DATA` frame contents into buffers,
create `ArrayBuffer` instances for all socket reads and emit
slices of those `ArrayBuffer`s to JS.

PR-URL: #18030
Reviewed-By: James M Snell <jasnell@gmail.com>
evanlucas pushed a commit that referenced this pull request Jan 30, 2018
Add a C++ variant of `Buffer.from(arrayBuffer, offset, length)`.

PR-URL: #18030
Reviewed-By: James M Snell <jasnell@gmail.com>
evanlucas pushed a commit that referenced this pull request Jan 30, 2018
Refactor the read mechanism to completely avoid copying.

Instead of copying individual `DATA` frame contents into buffers,
create `ArrayBuffer` instances for all socket reads and emit
slices of those `ArrayBuffer`s to JS.

PR-URL: #18030
Reviewed-By: James M Snell <jasnell@gmail.com>
evanlucas pushed a commit that referenced this pull request Jan 30, 2018
Add a C++ variant of `Buffer.from(arrayBuffer, offset, length)`.

PR-URL: #18030
Reviewed-By: James M Snell <jasnell@gmail.com>
evanlucas pushed a commit that referenced this pull request Jan 30, 2018
Refactor the read mechanism to completely avoid copying.

Instead of copying individual `DATA` frame contents into buffers,
create `ArrayBuffer` instances for all socket reads and emit
slices of those `ArrayBuffer`s to JS.

PR-URL: #18030
Reviewed-By: James M Snell <jasnell@gmail.com>
@MylesBorins
Copy link
Contributor

Should this be backported to v8.x-staging? If yes please follow the guide and raise a backport PR, if not let me know or add the dont-land-on label.

@addaleax addaleax removed the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Apr 1, 2018
kjin pushed a commit to kjin/node that referenced this pull request May 1, 2018
Add a C++ variant of `Buffer.from(arrayBuffer, offset, length)`.

PR-URL: nodejs#18030
Reviewed-By: James M Snell <jasnell@gmail.com>
kjin pushed a commit to kjin/node that referenced this pull request May 1, 2018
Refactor the read mechanism to completely avoid copying.

Instead of copying individual `DATA` frame contents into buffers,
create `ArrayBuffer` instances for all socket reads and emit
slices of those `ArrayBuffer`s to JS.

PR-URL: nodejs#18030
Reviewed-By: James M Snell <jasnell@gmail.com>
MylesBorins pushed a commit that referenced this pull request May 2, 2018
Add a C++ variant of `Buffer.from(arrayBuffer, offset, length)`.

Backport-PR-URL: #20456
PR-URL: #18030
Reviewed-By: James M Snell <jasnell@gmail.com>
MylesBorins pushed a commit that referenced this pull request May 2, 2018
Refactor the read mechanism to completely avoid copying.

Instead of copying individual `DATA` frame contents into buffers,
create `ArrayBuffer` instances for all socket reads and emit
slices of those `ArrayBuffer`s to JS.

Backport-PR-URL: #20456
PR-URL: #18030
Reviewed-By: James M Snell <jasnell@gmail.com>
@MylesBorins MylesBorins mentioned this pull request May 2, 2018
MayaLekova pushed a commit to MayaLekova/node that referenced this pull request May 8, 2018
Add a C++ variant of `Buffer.from(arrayBuffer, offset, length)`.

PR-URL: nodejs#18030
Reviewed-By: James M Snell <jasnell@gmail.com>
MayaLekova pushed a commit to MayaLekova/node that referenced this pull request May 8, 2018
Refactor the read mechanism to completely avoid copying.

Instead of copying individual `DATA` frame contents into buffers,
create `ArrayBuffer` instances for all socket reads and emit
slices of those `ArrayBuffer`s to JS.

PR-URL: nodejs#18030
Reviewed-By: James M Snell <jasnell@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
http2 Issues or PRs related to the http2 subsystem. lib / src Issues and PRs related to general changes in the lib or src directory.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants